package com.xncoding.freemarker.ctr;

import com.alibaba.fastjson.JSON;
import com.xncoding.freemarker.utile.SFtpUtil;
import com.xncoding.freemarker.utile.SftpVo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.apache.commons.codec.binary.Base64;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@RequestMapping("/upload/")
@RestController
public class UploadSftpController {
    protected Log log = LogFactory.getLog(this.getClass());

    @RequestMapping("/hello")
    public String helloWorld() {
        log.info("helloWorld");
        return "helloWorld";
    }

    @RequestMapping("/uploadWithSftp")
    public Map uploadWithSftp(@RequestBody Map<String, String> params) {
//        log.info("上传文件参数："+JSON.toJSONString(params)); 谨慎文件太大，不要全部打印
        Map<String, String> response = new HashMap<>();
        String fileData = params.get("fileData");//数据字符串
        String filePath = params.get("filePath");//上传相对路径
        String fileName = params.get("fileName");//文件名
        String sftpIp = params.get("sftpIp");//sftp-ip
        int sftpPort = Integer.valueOf(params.get("sftpPort"));//sftp-端口
        String sftpUserName = params.get("sftpUserName");//用户名
        String sftpPassword = params.get("sftpPassword");//密码
        String sftpPath = params.get("sftpPath");//sftp根路径
        String serverPath = params.get("serverPath");//本地存放路径
        String privateKeyPath = params.get("privateKeyPath");//登录私钥存放路径,包含文件名
        String seriaNo = params.get("seriaNo");
        String CnsmrSeqNo = params.get("CnsmrSeqNo");

        log.info("上传文件参数："+sftpIp + ":"+ sftpUserName + ":"+ sftpPassword + ":"+sftpPath+filePath+fileName );
        log.info("上传文件预存参数："+privateKeyPath);
        log.info("seriaNo："+seriaNo+"CnsmrSeqNo"+CnsmrSeqNo);

        try {
            //生成本地文件
            createFile(serverPath, fileName, Base64.decodeBase64(fileData));
            //上传京东sftp
            SftpVo sftpVo = new SftpVo();
            sftpVo.setIp(sftpIp);
            sftpVo.setPort(sftpPort);
            sftpVo.setUser(sftpUserName);
            sftpVo.setPassword(sftpPassword);
            sftpVo.setUploadSftpDirName(sftpPath + filePath);
            sftpVo.setUploadDirName(serverPath);
            sftpVo.setFileName(fileName);
            sftpVo.setPrivateKeyPath(privateKeyPath);
            sftpVo.setFlagPrivateKeyPath("1");//1  为绝对路径   0为相对路径。

            if (SFtpUtil.uploadFile(sftpVo)) {
                log.info(seriaNo+"上传成功,保存路径" + sftpVo.getUploadSftpDirName() + fileName);
                response.put("result", "success");
                response.put("message", "交易成功");
            }

        } catch (Exception e) {
            response.put("result", "fail");
            response.put("message", "上传失败"+e.getMessage());
            log.error(seriaNo+"生成本地文件或者上传失败"+e.getMessage(),e);
        } finally {
            File file = new File(serverPath + fileName);
            if (file.exists()) {
                boolean delete = file.delete();
                log.info(seriaNo+"上传SFTP后删除文件:" + serverPath + fileName + "," + (delete ? "成功" : "失败"));
            }
        }
        log.info(seriaNo+"uploadWithSftp返回参数："+JSON.toJSONString(response));
        return response;
    }

    @RequestMapping("/uploadWithLocal")
    public Map uploadWithLocal(@RequestBody Map<String, String> params) {
//        log.info("上传文件参数："+JSON.toJSONString(params)); 谨慎文件太大，不要全部打印
        Map<String, String> response = new HashMap<>();
        String fileData = params.get("fileData");//数据字符串
        String fileName = params.get("fileName");//文件名
        String seriaNo = params.get("seriaNo");
        String serverPath = params.get("serverPath");//本地存放路径
        log.info("文件名："+fileName + "流水号:"+ seriaNo + "本地路径:"+ serverPath );

        try {
            //生成本地文件
            boolean b = createFile(serverPath, fileName, Base64.decodeBase64(fileData));
            try {
                if (b) {
                    log.info(seriaNo+"上传成功,保存路径" + serverPath + fileName);
                    response.put("result", "success");
                    response.put("message", "交易成功");
                } else {
                    log.info(seriaNo+"上传失败");
                    response.put("result", "fail");
                    response.put("message", "上传失败");
                }
            } catch (Exception e) {
                response.put("result", "fail");
                response.put("message", "上传过程失败"+e.getMessage());
                log.error(seriaNo+e.getMessage(),e);
            }
        } catch (Exception e) {
            response.put("result", "fail");
            response.put("message", "上传失败"+e.getMessage());
            log.error(seriaNo+"生成本地文件或者上传失败"+e.getMessage(),e);
        } finally {
            log.info(seriaNo+"uploadWithLocal返回参数："+JSON.toJSONString(response));
        }

        return response;
    }

    private boolean createFile(String filePath, String fileName, byte[]  data) {
        File dir = new File(filePath);
        // 一、检查放置文件的文件夹路径是否存在，不存在则创建
        if (!dir.exists()) {
            dir.mkdirs();// mkdirs创建多级目录
        }

        boolean flages = false;
        File tofile = new File(filePath+fileName);
        FileOutputStream outputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {//如果文件存在，则会覆盖
            outputStream = new FileOutputStream(tofile);
            if ( null != outputStream) {
                bufferedOutputStream = new BufferedOutputStream(outputStream);
                bufferedOutputStream.write(data);
            }
            flages = true;
            log.info("文件创构建成功"+filePath+fileName);
        } catch (Exception e) {
            log.error(e);
            flages = false;
            log.info("文件创构建失败"+e.getMessage());
        }finally {
            if (null != bufferedOutputStream) {
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    log.info("关闭流失败"+e.getMessage());
                }
            }
            if (null != outputStream) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    log.info("关闭流失败"+e.getMessage());
                }
            }
        }
        return flages;
    }


}
